#include "watermarking.h"

unsigned long extractMethod(const sample_t dataShort) {
    unsigned long bitsReversed = 0;
    unsigned long bits = 0;

    unsigned i = 0;
    unsigned short extractedBit;
    double * doubleConverted = data;
    sample_t shortSample = (sample_t) dataShort;
    double * nextBlock;

    /* convert to double */
    for (i = 0; i < MARK_SAMPLES; i++) {
        //fast way to cast to doyble
        *doubleConverted++ = *shortSample++;
    }

    DWT(data, approx, detail);

    /* Here must be extracted the information */
    nextBlock = approx;
    for (i = 0; i < MARK_BITS_TO_CODE; i++) {
        extractedBit = 0;

        getHidenBit(nextBlock, &extractedBit);

        nextBlock += MARK_SPEC_SAMPLES_PER_BIT;

#if TEST_WATERMARKING
#endif
        bits = bits >> 1;
        bits = extractedBit == 0 ? bits & 0x7fffffff : bits | 0x80000000;
    }
    for (; i < 32; i++) {
        bits = bits >> 1;
        bits = bits & 0x7fffffff;
    }
#if TEST_WATERMARKING
#endif
    return bits;
}

void embedMethod(sample_t dataShort, const unsigned long mark) {
    unsigned long bits = mark;
    unsigned i = 0;

    unsigned short bit = 0;
    double * nextBlock;

    double * doubleConverted = data;
    short * shortSample = dataShort;
#if TEST_WATERMARKING
    unsigned short recoveredBit;
    unsigned encerts = 0;
    unsigned total = 0;
#endif

    //Very fast cast from short to double
    for (i = 0; i < MARK_SAMPLES; i++) {
        *doubleConverted++ = *shortSample++;
    }

    /* Gone to the frecuency domain */
    DWT(data, approx, detail);

    /* marking the bits */
    nextBlock = approx;
    for (i = 0; i < MARK_BITS_TO_CODE; i++) {
        bit = (unsigned short) (bits & 0x00000001);
        bits = bits >> 1;

        if (bit > 0)
            hideBit(nextBlock, 1);
        else
            hideBit(nextBlock, 0);

#if TEST_WATERMARKING
        getHidenBit(nextBlock, &recoveredBit);
        if (bit == recoveredBit) encerts++;
        total++;
#endif

        nextBlock += MARK_SPEC_SAMPLES_PER_BIT;
    }
#if TEST_WATERMARKING
#endif
    /* Back to the Temporal Domain */
    iDWT(approx, detail, data);

#if TEST_WATERMARKING
#endif
    //Very fast cast from double to short
    doubleConverted = data;
    shortSample = dataShort;
    for (i = 0; i < MARK_SAMPLES; i++) {
        *shortSample++ = (int) (0.5 + (*doubleConverted++));
    }
}
